package com.xiayuxuanmin.weixinpay.servlet;

import com.xiayuxuanmin.weixinpay.utils.PayCommonUtil;
import com.xiayuxuanmin.weixinpay.utils.PayConfigUtil;
import com.xiayuxuanmin.weixinpay.utils.XMLUtil;
import org.apache.log4j.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.websocket.Session;
import java.io.*;
import java.util.*;

/**
 * 用于响应微信支付结果的servlet
 * @Author xiayuxuanmin
 * @Date 2019/8/8
 * @Description
 */
public class ResultServlet extends HttpServlet {

    private static Logger logger = Logger.getLogger("wapshop_log");

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try {
            weixin_notify(req,resp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }

    public void weixin_notify(HttpServletRequest request,HttpServletResponse response) throws Exception{
        String writeContent = "默认支付失败!";//因为没有重定向,所以测试的时候无法知道支付结果,因此将支付结果写入文件,实际开发中删除
        String path = request.getServletContext().getRealPath("")+File.separator+"file";//保存支付结果的文件的位置
        //如果改为:String path = request.getServletContext().getRealPath("file"),返回值为null,在new File(path)报空指针
        //this.getClass().getClassLoader().getResource("")-->file:/D:/apache-tomcat-8.0.17/webapps/weixinpay/WEB-INF/classes/
        //this.getClass().getClassLoader().getResource("../")-->file:/D:/apache-tomcat-8.0.17/webapps/weixinpay/WEB-INF/
        //this.getClass().getClassLoader().getResource("../../")-->file:/D:/apache-tomcat-8.0.17/webapps/weixinpay
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
        FileOutputStream fileOutputStream = new FileOutputStream(path+"/result.txt");

        //读取参数
        InputStream inputStream ;
        StringBuffer sb = new StringBuffer();
        inputStream = request.getInputStream();
        String s ;
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        while ((s = in.readLine()) != null){
            sb.append(s);
        }
        in.close();
        inputStream.close();

        //解析xml成map
        Map<String, String> m = new HashMap<String, String>();
        m = XMLUtil.doXMLParse(sb.toString());

        //过滤空 设置 TreeMap
        SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();
        Iterator it = m.keySet().iterator();
        while (it.hasNext()) {
            String parameter = (String) it.next();
            String parameterValue = m.get(parameter);

            String v = "";
            if(null != parameterValue) {
                v = parameterValue.trim();
            }
            packageParams.put(parameter, v);
        }

        // 账号信息
        String key = PayConfigUtil.API_KEY; // key
        logger.info(packageParams);

        String out_trade_no = (String)packageParams.get("out_trade_no");
        //判断签名是否正确
        if(PayCommonUtil.isTenpaySign("UTF-8", packageParams,key)) {
            //------------------------------
            //处理业务开始
            //------------------------------
            String resXml = "";
            if("SUCCESS".equals((String)packageParams.get("result_code"))){
                // 这里是支付成功
                //////////执行自己的业务逻辑////////////////
                String mch_id = (String)packageParams.get("mch_id");
                String openid = (String)packageParams.get("openid");
                String is_subscribe = (String)packageParams.get("is_subscribe");
//                String out_trade_no = (String)packageParams.get("out_trade_no");

                String total_fee = (String)packageParams.get("total_fee");

                logger.info("mch_id:"+mch_id);
                logger.info("openid:"+openid);
                logger.info("is_subscribe:"+is_subscribe);
                logger.info("out_trade_no:"+out_trade_no);
                logger.info("total_fee:"+total_fee);

                //////////执行自己的业务逻辑////////////////

                logger.info("支付成功");
                writeContent = "订单:"+out_trade_no+"支付成功!";//拼接支付结果,写入文件
                //通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.
                resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                //知道支付成功了,此时应该通知页面支付成功,并让页面执行跳转动作
                //需要websocket(所以打开扫码页面的时候,应该建立页面的websocket和服务器连接,如果服务器知道支付成功,找到对应的websocket,并发送消息)
                /*Session session = WebSocket.getAllClients().get(out_trade_no);//当前页面的订单号对应的session
                if (session != null) {
                    session.getAsyncRemote().sendText("支付成功了呢!");//实际开发中,请发送正式数据,比如JSON数据
                }*/
                WebSocket.sendMessage(out_trade_no,"支付成功");
            } else {
                logger.info("支付失败,错误信息：" + packageParams.get("err_code"));
                writeContent = "订单:"+out_trade_no+"支付失败!错误信息:"+packageParams.get("err_code");//将支付结果写入文件,实际开发中删除
                resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                        + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
            }
            //------------------------------
            //处理业务完毕
            //------------------------------
            BufferedOutputStream out = new BufferedOutputStream(
                    response.getOutputStream());
            out.write(resXml.getBytes());
            out.flush();
            out.close();
        } else{
            writeContent = "订单:"+out_trade_no+"通知签名验证失败!";//拼接支付结果,写入文件
            logger.info("通知签名验证失败");
        }
        fileOutputStream.write(writeContent.getBytes("UTF-8"));//将支付结果写入文件,实际开发中删除
        fileOutputStream.close();
    }
}
